import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutterdome/config/app_config.dart';
import 'dio_interceptors.dart' as custom_interceptors;

class ApiService {
  static final ApiService _instance = ApiService._internal();
  factory ApiService() => _instance;

  late Dio _dio;
  final List<CancelToken> _cancelTokens = [];

  ApiService._internal() {
    _dio = Dio(
      BaseOptions(
        baseUrl: AppConfig.baseUrl,
        connectTimeout: const Duration(seconds: 30),
        receiveTimeout: const Duration(seconds: 30),
        contentType: 'application/json',
        responseType: ResponseType.json,
      ),
    );

    // 添加拦截器
    _dio.interceptors.add(custom_interceptors.AuthInterceptor());
    _dio.interceptors.add(custom_interceptors.LogInterceptor());
    _dio.interceptors.add(custom_interceptors.ErrorInterceptor());
  }

  /// 通用请求方法
  Future<Response<T>> request<T>(
    String path,
    {
    String? baseUrl,
    String method = 'GET',
    Map<String, dynamic>? queryParameters,
    dynamic data,
    Map<String, dynamic>? headers,
    bool formData = false,
  }) async {
    // 如果提供了自定义baseUrl，则使用它，否则使用默认配置的baseUrl
    final options = Options(
      method: method,
      headers: headers,
    );
    
    // 创建cancel token并添加到列表
    final cancelToken = CancelToken();
    _cancelTokens.add(cancelToken);

    try {
      if (formData && data != null && data is Map<String, dynamic>) {
        data = FormData.fromMap(data);
      }
      
      // 使用自定义baseUrl时需要拼接完整URL
      final requestPath = baseUrl != null ? '$baseUrl$path' : path;
      
      return await _dio.request<T>(
        requestPath,
        queryParameters: queryParameters,
        data: data,
        options: options,
        cancelToken: cancelToken,
      );
    } catch (e) {
      rethrow;
    } finally {
      // 请求完成后移除cancel token
      _cancelTokens.remove(cancelToken);
    }
  }

  /// GET请求
  Future<Response<T>> get<T>(
    String path,
    {
    String? baseUrl,
    Map<String, dynamic>? queryParameters,
    Map<String, dynamic>? headers,
  }) async {
    return await request<T>(
      path,
      baseUrl: baseUrl,
      method: 'GET',
      queryParameters: queryParameters,
      headers: headers,
    );
  }

  /// POST请求
  Future<Response<T>> post<T>(
    String path,
    {
    String? baseUrl,
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Map<String, dynamic>? headers,
    bool formData = false,
  }) async {
    return await request<T>(
      path,
      baseUrl: baseUrl,
      method: 'POST',
      data: data,
      queryParameters: queryParameters,
      headers: headers,
      formData: formData,
    );
  }

  /// PUT请求
  Future<Response<T>> put<T>(
    String path,
    {
    String? baseUrl,
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Map<String, dynamic>? headers,
    bool formData = false,
  }) async {
    return await request<T>(
      path,
      baseUrl: baseUrl,
      method: 'PUT',
      data: data,
      queryParameters: queryParameters,
      headers: headers,
      formData: formData,
    );
  }

  /// DELETE请求
  Future<Response<T>> delete<T>(
    String path,
    {
    String? baseUrl,
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Map<String, dynamic>? headers,
  }) async {
    return await request<T>(
      path,
      baseUrl: baseUrl,
      method: 'DELETE',
      data: data,
      queryParameters: queryParameters,
      headers: headers,
    );
  }

  /// 上传文件
  Future<Response<T>> uploadFile<T>(
    String path,
    String filePath,
    {
    String? fileName,
    String? fileKey = 'file',
    String? baseUrl,
    Map<String, dynamic>? data,
    Map<String, dynamic>? headers,
    ProgressCallback? onSendProgress,
  }) async {
    final file = File(filePath);
    final formData = FormData.fromMap({
      if (data != null) ...data,
      fileKey!: await MultipartFile.fromFile(
        file.path,
        filename: fileName ?? file.path.split('/').last,
      ),
    });

    return await post<T>(
      path,
      baseUrl: baseUrl,
      data: formData,
      headers: headers,
    );
  }

  /// 批量上传文件
  Future<Response<T>> uploadFiles<T>(
    String path,
    List<String> filePaths,
    {
    String? fileKey = 'files',
    String? baseUrl,
    Map<String, dynamic>? data,
    Map<String, dynamic>? headers,
    ProgressCallback? onSendProgress,
  }) async {
    final formData = FormData.fromMap({
      if (data != null) ...data,
      fileKey!: await Future.wait(
        filePaths.map((filePath) async {
          final file = File(filePath);
          return await MultipartFile.fromFile(
            file.path,
            filename: file.path.split('/').last,
          );
        }),
      ),
    });

    return await post<T>(
      path,
      baseUrl: baseUrl,
      data: formData,
      headers: headers,
    );
  }

  /// 下载文件
  Future<Response<dynamic>> download(
    String url,
    String savePath,
    {
    Map<String, dynamic>? queryParameters,
    Map<String, dynamic>? headers,
    ProgressCallback? onReceiveProgress,
    CancelToken? cancelToken,
  }) async {
    // 如果提供了cancelToken，添加到列表
    if (cancelToken != null) {
      _cancelTokens.add(cancelToken);
    }
    
    try {
      return await _dio.download(
        url,
        savePath,
        queryParameters: queryParameters,
        onReceiveProgress: onReceiveProgress,
        cancelToken: cancelToken,
        options: Options(headers: headers),
      );
    } catch (e) {
      rethrow;
    } finally {
      // 请求完成后移除cancel token
      if (cancelToken != null) {
        _cancelTokens.remove(cancelToken);
      }
    }
  }

  /// 获取Dio实例（用于特殊需求）
  Dio get dio => _dio;

  /// 取消所有请求
  void cancelAllRequests() {
    for (var token in _cancelTokens) {
      if (!token.isCancelled) {
        token.cancel('Cancelled all requests');
      }
    }
    _cancelTokens.clear();
  }
}